package com.kgc.scd.resolver;

import com.alibaba.fastjson.JSON;
import com.kgc.scd.annotation.RequestShopUser;
import com.kgc.scd.bean.ShopUser;
import com.kgc.scd.util.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * Created On : 2022/11/4 0004.
 * <p>
 * Author : shiguangchuan
 * <p>
 * Description: 自定义我们的请求用户解析器，自动根据@RequestUser注解，解析通过鉴权的用户信息，绑定到请求处理方法的用户参数上，要配合请求token许可鉴权使用
 */
public class MyDefineShopUserResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        // 决定是否需要执行参数解析，如果你的目标请求方法使用了自定义参数注解@RequestUser，且目标实体参数类型是User，就需要进行解析，否则不需要解析
        // 注意查找注解的位置是在参数上查是否添加注解
        return methodParameter.hasParameterAnnotation(RequestShopUser.class) && methodParameter.getParameterType().isAssignableFrom(ShopUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        // 根据上面supportsParameter方法，如果返回的是true，代表需要执行方法参数解析，如果返回false，不需要执行参数解析
        // 从redis中获取token令牌保存的用户信息，转换为目标用户对象，绑定到请求处理方法的入参中，前提：鉴权是通过

        // TODO 在获取redis中保存的用户信息时，需要做非空校验，防止解析时过期
        return JSON.parseObject(redisUtils.get(nativeWebRequest.getHeader("token")).toString(), ShopUser.class);

    }
}
